#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
////////////////////////////////
#include "cmsis_os2.h"
#include "securec.h" 

/* 任务ID */
static osThreadId_t g_testTaskId01;
static osThreadId_t g_testTaskId02;
/* 测试任务优先级 */
#define TASK_PRIO_TEST  osPriorityNormal
/* 信号量结构体id */
static osSemaphoreId_t g_semId;

void Example_SemTask1(void *argument)
{
    osStatus_t ret;

    printf("Example_SemTask1 try get sem g_semId ,timeout 10 ticks.\n");
    /* 定时阻塞模式申请信号量，定时时间为10ticks */
    ret = osSemaphoreAcquire(g_semId, 10);

    /* 申请到信号量 */
    if (ret == osOK) {
         osSemaphoreRelease(g_semId);
         return;
    }
    /* 定时时间到，未申请到信号量 */
    if (ret == osErrorTimeout) {
        printf("Example_SemTask1 timeout and try get sem g_semId wait forever.\n");
        /*永久阻塞模式申请信号量*/
        ret = osSemaphoreAcquire(g_semId, osWaitForever);
        printf("Example_SemTask1 wait_forever and get sem g_semId .\n");
        if (ret == osOK) {
            osSemaphoreRelease(g_semId);
            return;
        }
    }
}

void Example_SemTask2(void *argument)
{
    osStatus_t ret;
    printf("Example_SemTask2 try get sem g_semId wait forever.\n");
    /* 永久阻塞模式申请信号量 */
    ret = osSemaphoreAcquire(g_semId, osWaitForever);

    if (ret == osOK) {
        printf("Example_SemTask2 get sem g_semId and then delay 20ticks .\n");
    }

    /* 任务休眠20 ticks */
    osDelay(20);

    printf("Example_SemTask2 post sem g_semId .\n");
    /* 释放信号量 */
    osSemaphoreRelease(g_semId);
    return;
}

uint32_t ExampleTaskEntry(void)
{
    osStatus_t ret;
    osThreadAttr_t task1Attr;
    osThreadAttr_t task2Attr;

    /* 创建信号量 */
    g_semId = osSemaphoreNew(1, 0, NULL);
    if (g_semId == NULL) {
        printf("Semaphore create failed.\n");
        return 1;
    }

    /* 设置任务1的属性 */
    task1Attr.name = "TestTsk1";
    task1Attr.attr_bits = 0U;
    task1Attr.cb_mem = NULL;
    task1Attr.cb_size = 0U;
    task1Attr.stack_mem = NULL;
    task1Attr.stack_size = 4096;  // 相当于LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE
    task1Attr.priority = TASK_PRIO_TEST;
    task1Attr.tz_module = 0;
    task1Attr.reserved = 0;

    /* 创建任务1 */
    g_testTaskId01 = osThreadNew(Example_SemTask1, NULL, &task1Attr);
    if (g_testTaskId01 == NULL) {
        printf("task1 create failed .\n");
        osSemaphoreDelete(g_semId);
        return 1;
    }

    /* 设置任务2的属性 */
    task2Attr.name = "TestTsk2";
    task2Attr.attr_bits = 0U;
    task2Attr.cb_mem = NULL;
    task2Attr.cb_size = 0U;
    task2Attr.stack_mem = NULL;
    task2Attr.stack_size = 4096;  // 相当于LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE
    task2Attr.priority = TASK_PRIO_TEST - 1;  // 优先级比任务1高
    task2Attr.tz_module = 0;
    task2Attr.reserved = 0;

    /* 创建任务2 */
    g_testTaskId02 = osThreadNew(Example_SemTask2, NULL, &task2Attr);
    if (g_testTaskId02 == NULL) {
        printf("task2 create failed .\n");
        osThreadTerminate(g_testTaskId01);
        osSemaphoreDelete(g_semId);
        return 1;
    }

    /* 释放信号量 */
    ret = osSemaphoreRelease(g_semId);
    if (ret != osOK) {
        printf("Failed to release semaphore.\n");
    }

    /* 任务休眠40 ticks */
    osDelay(40);

    /* 删除信号量 */
    osSemaphoreDelete(g_semId);

    /* 删除任务1 */
    osThreadTerminate(g_testTaskId01);
    
    /* 删除任务2 */
    osThreadTerminate(g_testTaskId02);

    return 0;
}

APP_FEATURE_INIT(ExampleTaskEntry);
